﻿using PloobsEngine.SceneControl;
using PloobsEngine.Physics;
using PloobsEngine;
using PloobsEngine.Cameras;
using PloobsEngine.Input;
using Microsoft.Xna.Framework;
using PloobsEngine.Physics.Bepu;
using PloobsEngine.Modelo;
using PloobsEngine.Material;
using Microsoft.Xna.Framework.Graphics;
using PloobsEngine.Features;
using PloobsEngine.Commands;
using PloobsEngineDemo3;
using PloobsEngine.Light;
using ModelXML;
using Etapa1.BezierExperiments;
using Etapa1.Import;
using PloobsEngine.Utils;
using Etapa1.Import.Anim;
using System;
using System.Collections.Generic;

namespace Etapa1.Screens
{    
    public class PTSScene : SceneScreen
    {
        private BepuPhysicWorld physicWorld;
        private BrutalForceWorld mundo;
        private EngineStuff engine;        
        ICamera cam;
        Etapa1.Import.Anim.Bone root;

        public PTSScene(EngineStuff es)
        {
            this.engine = es;
            physicWorld = new BepuPhysicWorld();
            mundo = new BrutalForceWorld(physicWorld);                                    
        }               
        
        public override void LoadContent(EngineStuff es)
        {            
            InputAdvanced inp = new InputAdvanced(engine);
            engine.AddComponent(inp);

            base.LoadContent(es);            

            #region Models

            Cena cena = Cena.LoadXmlContent(@"C:\Users\tpastor\Documents\3dsMax\export\cam.xml");           

            foreach (var item in cena.Modelos)
	        {
                if (item.SkinInfo != null)
                {
                    Matrix[] boneMatrix;
                    root = Etapa1.Import.Anim.Bone.CreateBoneHierarchy(item, out boneMatrix);

                    AnimatedModel am = new AnimatedModel(item, root);
                    am.LoadModelo();
                    ImportAnimationShader sh = new ImportAnimationShader(FillMode.WireFrame,root);
                    sh.Initialize();
                    TriangleMeshObject tm = new TriangleMeshObject(Vector3.Zero, am);
                    IMaterial m = new Material(sh);
                    IObject obj = new SimpleObject(m, tm, am);
                    mundo.AddObject(obj);


                    Animations anim = Animations.LoadAnimations(item);

                }

                LoadedModel sm = new LoadedModel(item, true);
                sm.LoadModelo();
                NormalDeferred shader = new NormalDeferred();
                shader.Initialize();
                TriangleMeshObject go = new TriangleMeshObject(Vector3.Zero, sm);
                //GhostObject go = new GhostObject();
                //go.setInternalWorldMatrix(Matrix.Identity);                
                IMaterial mat = new Material(shader);
                IObject obj3 = new SimpleObject(mat, go, sm);
                mundo.AddObject(obj3);
	        }           
 
            #endregion            

            //cam = new CameraFirstPerson(true);            
            //cam.FarPlane = 2000;

            List<CameraStatic> cameras = new List<CameraStatic>();
            foreach (var item in cena.Cameras)
            {
                CameraStatic cs = new CameraStatic(ImporterHelper.toVector3(item.Position), ImporterHelper.toVector3(item.Target));
                //cs.FieldOfView = item.Fov;
                //cs.NearPlane = item.NearPlane;
                //cs.FarPlane = item.FarPlane;
                cs.Name = item.Name;
                cameras.Add(cs);
            }
            cam = cameras[0];

            LightThrowBepu lt = new LightThrowBepu(mundo, engine);         

            #region NormalLight
            DirectionalLight ld1 = new DirectionalLight(Vector3.Left, Color.White);
            DirectionalLight ld2 = new DirectionalLight(Vector3.Right, Color.White);
            DirectionalLight ld3 = new DirectionalLight(Vector3.Backward, Color.White);
            DirectionalLight ld4 = new DirectionalLight(Vector3.Forward, Color.White);
            DirectionalLight ld5 = new DirectionalLight(Vector3.Down, Color.White);
            float li = 0.4f;
            ld1.LightIntensity = li;
            ld2.LightIntensity = li;
            ld3.LightIntensity = li;
            ld4.LightIntensity = li;
            ld5.LightIntensity = li;
            mundo.AddLight(ld1);
            mundo.AddLight(ld2);
            mundo.AddLight(ld3);
            mundo.AddLight(ld4);
            mundo.AddLight(ld5);
            #endregion

            ////Criacao de uma Tecnica
            DeferredRenderTechnic dr = new DeferredRenderTechnic(engine);
            
            IRenderTechnic[] rt = new IRenderTechnic[] { dr };
            this.RenderTechnics = rt;
            dr.isDebug = true;
            mundo.AddCamera(cam);
            this.World = mundo;
        }

        Vector3 toVector3(Ponto3D point)
        {
            return new Vector3(point.x, point.y, point.z);
        }

        Quaternion toQuaternion(Ponto4D point)
        {
            return new Quaternion(point.x, point.y, point.z, point.w);
        }

        Vector2 toVector2(Ponto2D point)
        {
            return new Vector2(point.x, point.y);
        }
    }
}